package com.datoucai.controller;

import cn.hutool.core.convert.Convert;
import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.alibaba.csp.sentinel.slots.block.authority.AuthorityRuleManager;
import com.alibaba.csp.sentinel.slots.block.flow.param.ParamFlowRuleManager;
import com.alibaba.fastjson.JSON;
import com.datoucai.dto.BatchQueryCommentDto;
import com.datoucai.dto.CommentDetailInfoDto;
import com.datoucai.dto.CommentInfoDto;
import com.datoucai.dto.CommentResultInfoDto;
import com.datoucai.enums.CommentDeleteEnum;
import com.datoucai.param.AddCommentRequestParam;
import com.datoucai.param.BaseResult;
import com.datoucai.param.CommentInfoEntity;
import com.datoucai.param.CommentResultParam;
import com.datoucai.param.DelCommentRequestParam;
import com.datoucai.param.PageResultWrapper;
import com.datoucai.param.QueryCommentRequestParam;
import com.datoucai.param.SimpleCommentDto;
import com.datoucai.param.SimpleCommentInfoDto;
import com.datoucai.rpc.MediaRpcService;
import com.datoucai.service.ICommentService;
import com.datoucai.utils.BaseResultUtils;
import com.datoucai.utils.DateUtils;
import com.datoucai.utils.TokenUtils;
import io.swagger.annotations.Api;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@RestController
@RequestMapping("/comment")
@Slf4j
@Api(tags = "评论模块")
public class CommentController {

    @Autowired
    private ICommentService commentService;

    @Autowired
    private MediaRpcService mediaRpcService;


    @RequestMapping(value = "/test/flow",method = RequestMethod.GET)
    public int testFlow(){
        log.info("test sentinel start");
        return 1;
    }
    @RequestMapping(value = "/test/degrade",method = RequestMethod.GET)
//    @SentinelResource(value = "testDegrade", fallback = "fallBack")
    public String testDegrade(@RequestParam("throwError") boolean throwError){
        System.out.println("正常处理请求");
        if (throwError) {
            System.out.println("触发异常");
            int i = 1/0;
        }
        return "Success";
    }
    @RequestMapping(value = "/test/auth",method = RequestMethod.GET)
    public String testAuth(){
        System.out.println(AuthorityRuleManager.getRules());
        System.out.println("正常处理请求");
        return "Success";
    }
    @RequestMapping(value = "/test/param/flow",method = RequestMethod.GET)
    @SentinelResource(value = "position",blockHandler = "paramFallback")
    public String testParam(@RequestParam("id") int id,@RequestParam("name") String name){
//        Entry entry = null;
//        try {
//            // 方法执行逻辑
//            entry = SphU.entry("position", EntryType.OUT,0, id,name); // args 是方法参数
//            System.out.println("正常处理请求:"+id+name);
//
//        } catch (BlockException e) {
//            log.error(e.getMessage());
//        } finally {
//            if (entry != null) {
//                entry.exit(0, id,name); // 释放资源并可能触发统计和检查逻辑
//            }
//            return "Success";
//        }
        System.out.println(ParamFlowRuleManager.getRules());
        System.out.println("正常处理请求:"+id+name);
        return "Success";
    }

    public String paramFallback(int id, String name, BlockException blockException) {
        return "fallback param:" + id + ", " + name;
    }
    public String fallBack(boolean throwError) {
        return "我降级了，别再访问了";
    }

    /**
     * 增加评论
     * @param param
     * @return
     */
    @RequestMapping(value = "/add",method = RequestMethod.POST)
    public BaseResult<Long> addComment(@RequestBody AddCommentRequestParam param){
        try {
            // 登录校验
            Long userId = TokenUtils.getUserId();
            String userName = TokenUtils.getUsername();
            Assert.isTrue(userId!=null,"用户未登录，不能发表评论");
            param.setUserId(userId+"");
            param.setUsername(userName);
            param.setAvatar(TokenUtils.getAvatar());
            // 打印日志
            log.info("增加评论-controller层-addComment-入参:{}", JSON.toJSONString(param));
            // 参数校验
            checkParam(param);
            CommentInfoDto dto = buildCommentInfoDto(param);
            int count = commentService.addComment(dto);
            log.info("增加评论-controller层-addComment-出参:{}", count);
            return BaseResultUtils.generateSuccess(dto.getId());
        }catch (Exception e){
            log.error("增加评论-controller层-addComment-异常:", e);
            return BaseResultUtils.generateFail("增加评论异常:"+e.getMessage());
        }
    }

    private void checkParam(AddCommentRequestParam param) {
        Assert.isTrue(param!=null,"入参不能为空");
        Assert.isTrue(StringUtils.isNotBlank(param.getUserId()),"用户id不能为空");
        Assert.isTrue(StringUtils.isNotBlank(param.getResourceId()),"资源id不能为空");
        Assert.isTrue(param.getModule()!=null,"模块不能为空");
        Assert.isTrue(StringUtils.isNotBlank(param.getContent()),"内容不能为空");
    }

    private static CommentInfoDto buildCommentInfoDto(AddCommentRequestParam param) {
        CommentInfoDto dto = new CommentInfoDto();
        dto.setUserId(Long.valueOf(param.getUserId()));
        dto.setUsername(param.getUsername());
        dto.setRepliedUsername(param.getRepliedUsername());
        dto.setAvatar(param.getAvatar());
        dto.setModule(param.getModule());
        dto.setResourceId(Long.valueOf(param.getResourceId()));
        dto.setContent(param.getContent());
        dto.setStatus(0);
        dto.setScore(param.getScore());
        dto.setStarNum(0);
        dto.setIsDelete(CommentDeleteEnum.NORMAL.getCode());
        dto.setCreateTime(new Date());
        dto.setUpdateTime(new Date());
        dto.setRootCommentId(StringUtils.isNotBlank(param.getRootCommentId())?Long.valueOf(param.getRootCommentId()) : null);
        dto.setParentCommentId(StringUtils.isNotBlank(param.getParentCommentId())?Long.valueOf(param.getParentCommentId()):null);
        return dto;
    }

    /**
     * 删除评论
     * @param param
     * @return
     */
    @RequestMapping(value = "/delete",method = RequestMethod.POST)
    public BaseResult<Boolean> deleteComment(@RequestBody DelCommentRequestParam param){
        try {
            log.info("删除评论-controller层-deleteComment-入参:{}", JSON.toJSONString(param));
            // 参数校验
            param.setUserId(TokenUtils.getUserId()+"");
            checkDeleteCommentParam(param);
            CommentInfoDto dto = getCommentInfoDto(param);
            int count = commentService.deleteComment(dto);
            log.info("删除评论-controller层-deleteComment-出参:{}", count);
            if(count<=0){
                return BaseResultUtils.generateFail("删除评论失败");
            }
            return BaseResultUtils.generateSuccess(count>0);
        }catch (Exception e){
            log.error("删除评论-controller层-deleteComment-异常:", e);
            return BaseResultUtils.generateFail("删除评论异常");
        }
    }
    /**
     * 删除评论
     * @param param
     * @return
     */
    @RequestMapping(value = "/delete/batch",method = RequestMethod.POST)
    public BaseResult<Boolean> batchDeleteComment(@RequestBody DelCommentRequestParam param){
        try {
            log.info("删除评论-controller层-deleteComment-入参:{}", JSON.toJSONString(param));
            // 参数校验
            List<String> ids = param.getIds();
            if(CollectionUtils.isEmpty(ids)){
                return BaseResultUtils.generateFail("参数不能为空");
            }
            for (int i = 0; i < ids.size(); i++) {
                String id = ids.get(i);
                param.setId(id);
                BaseResult<Boolean> booleanBaseResult = deleteComment(param);
                log.info("删除评论-ID:{},结果:{}",id,booleanBaseResult.getSuccess());
            }
            return BaseResultUtils.generateSuccess(ids.size()>0);
        }catch (Exception e){
            log.error("删除评论-controller层-deleteComment-异常:", e);
            return BaseResultUtils.generateFail("删除评论异常");
        }
    }

    private void checkDeleteCommentParam(DelCommentRequestParam param) {
        Assert.isTrue(param!=null,"参数不能为空");
        Assert.isTrue(param.getModule()!=null,"模块不能为空");
        Assert.isTrue(StringUtils.isNotBlank(param.getUserId()),"用户id不能为空");
        Assert.isTrue(StringUtils.isNotBlank(param.getId()),"评论id不能为空");
    }

    private static CommentInfoDto getCommentInfoDto(DelCommentRequestParam param) {
        CommentInfoDto dto = new CommentInfoDto();
        dto.setId(Long.valueOf(param.getId()));
        dto.setIds(param.getIds());
        dto.setUserId(Long.valueOf(param.getUserId()));
        dto.setResourceId(param.getResourceId());
        dto.setUpdateTime(new Date());
        dto.setIsDelete(CommentDeleteEnum.DELETED.getCode());
        dto.setModule(param.getModule());
        return dto;
    }


    /**
     * 查询评论详情
     * @param id
     * @return
     */
    @RequestMapping(value = "/query/detail",method = RequestMethod.GET)
    public BaseResult<CommentInfoEntity> queryCommentDetail(@RequestParam("id") String id){
        try {
            Assert.isTrue(StringUtils.isNotBlank(id),"评论ID不能为空");
            log.info("查询评论详情-controller层-queryCommentDetail-入参:{}", id);
            CommentDetailInfoDto resultInfoDto = commentService.queryCommentDetailById(Long.valueOf(id));
            CommentInfoEntity commentInfoEntity = buildCommentInfoEntity(resultInfoDto);
            log.info("查询评论详情-controller层-queryCommentDetail-出参:{}", JSON.toJSONString(commentInfoEntity));
            return BaseResultUtils.generateSuccess(commentInfoEntity);
        }catch (Exception e){
            log.error("查询评论详情-controller层-queryCommentDetail-异常:", e);
            return BaseResultUtils.generateFail("查询评论详情异常:"+e.getMessage());
        }
    }

    /**
     * 查询评论列表
     * @param param
     * @return
     */
    @RequestMapping(value = "/query",method = RequestMethod.GET)
    public PageResultWrapper<CommentInfoEntity> queryComment(QueryCommentRequestParam param){
        try {
            Assert.isTrue(param!=null,"入参不能为空");
            Assert.isTrue(param.getPageNum()>=1,"页码不能小于1");
            Assert.isTrue(param.getPageSize()>=1,"每页条数不能小于1");
            Assert.isTrue(param.getModule()!=null,"模块不能为空");
            Assert.isTrue(param.getReplyNum()!=null,"子回复数量不能为空");
            Assert.isTrue(StringUtils.isNotBlank(param.getResourceId()),"资源id不能为空");

            log.info("查询评论-controller层-queryComment-入参:{}", JSON.toJSONString(param));
            CommentInfoDto commentInfoDto = buildCommentInfoDto(param);
            CommentResultInfoDto resultInfoDto = commentService.queryCommentByParam(commentInfoDto);
            CommentResultParam resultParam = buildCommentResultParam(resultInfoDto);
            log.info("查询评论-controller层-queryComment-出参:{}", JSON.toJSONString(resultParam));
            return PageResultWrapper.page(resultParam.getList(),resultParam.getTotal()!=null?resultParam.getTotal().intValue():0, param.getPageNum(), param.getPageSize());
        }catch (Exception e){
            log.error("查询评论-controller层-queryComment-异常:", e);
            return PageResultWrapper.fail("-1","查询评论异常:"+e.getMessage());
        }
    }

    /**
     * 根据资源id查评论
     * @return
     */
    @RequestMapping(value = "/batch/query",method = RequestMethod.GET)
    public BaseResult<List<SimpleCommentDto>> batchQueryCommentByResourceIds(@RequestParam("module") Integer module,
                                                                             @RequestParam("resourceIds") List<String> resourceIds
    ){
        try {
            Assert.isTrue(module!=null,"模块不能为空");
            Assert.isTrue(!CollectionUtils.isEmpty(resourceIds),"资源id不能为空");
            Assert.isTrue(resourceIds.size()<=100,"资源id不能超过100");

            log.info("批量查询评论-batchQueryCommentByResourceIds-入参:{},{}", module,resourceIds);
            BatchQueryCommentDto batchQueryCommentDto = new BatchQueryCommentDto();
            batchQueryCommentDto.setModule(module);
            batchQueryCommentDto.setResourceIds(Convert.toList(Long.class, resourceIds));
            List<SimpleCommentInfoDto> simpleCommentInfoDtos = commentService.batchQueryCommentByResourceIds(batchQueryCommentDto);
            // 构建结果集
            List<SimpleCommentDto> targetList = buildSimpleCommentDtos(simpleCommentInfoDtos);
            log.info("批量查询评论-batchQueryCommentByResourceIds-出参:{}", JSON.toJSONString(targetList));
            return BaseResultUtils.generateSuccess(targetList);
        }catch (Exception e){
            log.error("批量查询评论-batchQueryCommentByResourceIds-异常:", e);
            return BaseResultUtils.generateFail(-1,"批量查询评论异常:"+e.getMessage());
        }
    }

    private static List<SimpleCommentDto> buildSimpleCommentDtos(List<SimpleCommentInfoDto> simpleCommentInfoDtos) {
        List<SimpleCommentDto> targetList = new ArrayList<>();
        for (int i = 0; i < simpleCommentInfoDtos.size(); i++) {
            SimpleCommentInfoDto simpleCommentInfoDto = simpleCommentInfoDtos.get(i);
            SimpleCommentDto simpleCommentDto = new SimpleCommentDto();
            simpleCommentDto.setCommentInfo(simpleCommentInfoDto);
            simpleCommentDto.setResourceId(simpleCommentInfoDto.getResourceId());
            targetList.add(simpleCommentDto);
        }
        return targetList;
    }


    /**
     * 查询所有评论
     * @return
     */
    @GetMapping(value = "/queryAll")
    PageResultWrapper<CommentInfoEntity> queryAll(
            @RequestParam("module")Integer module,
          @RequestParam("pageNum")Integer pageNum,
          @RequestParam("pageSize")Integer pageSize,
          @RequestParam(value = "userId",required=false)String userId
            ) {
        try {
            Assert.isTrue(pageNum>=1,"页码不能小于1");
            Assert.isTrue(pageSize>=1,"每页条数不能小于1");
            Assert.isTrue(module!=null,"模块不能为空");

            QueryCommentRequestParam param = new QueryCommentRequestParam();
            param.setModule(module);
            param.setPageNum(pageNum);
            param.setPageSize(pageSize);
            param.setUserId(userId);

            log.info("查询评论-controller层-queryByUserId-入参:{}", JSON.toJSONString(param));
            CommentInfoDto commentInfoDto = buildCommentInfoDto(param);
            CommentResultInfoDto resultInfoDto = commentService.queryCommentList(commentInfoDto);
            CommentResultParam resultParam = buildCommentResultParam(resultInfoDto);
            log.info("查询评论-controller层-queryByUserId-出参:{}", JSON.toJSONString(resultParam));
            return PageResultWrapper.page(resultParam.getList(),resultParam.getTotal().intValue(), param.getPageNum(), param.getPageSize());
        }catch (Exception e){
            log.error("查询评论-controller层-queryByUserId-异常:", e);
            return PageResultWrapper.fail("-1","查询评论异常:"+e.getMessage());
        }
    }

    /**
     * 查询评论和回复列表
     * @param
     * @return
     */
    @GetMapping(value = "/queryByUserId")
    PageResultWrapper<CommentInfoEntity> queryCommentByUserId(@RequestParam("userId")Integer userId,
                                                              @RequestParam("module")Integer module,
                                                              @RequestParam("pageNum")Integer pageNum,
                                                              @RequestParam("pageSize")Integer pageSize) {
        try {
            Assert.isTrue(pageNum>=1,"页码不能小于1");
            Assert.isTrue(pageSize>=1,"每页条数不能小于1");
            Assert.isTrue(module!=null,"模块不能为空");
            Assert.isTrue(userId!=null,"用户ID不能为空");

            QueryCommentRequestParam param = new QueryCommentRequestParam();
            param.setUserId(userId+"");
            param.setModule(module);
            param.setPageNum(pageNum);
            param.setPageSize(pageSize);

            log.info("查询评论-controller层-queryByUserId-入参:{}", JSON.toJSONString(param));
            CommentInfoDto commentInfoDto = buildCommentInfoDto(param);
            CommentResultInfoDto resultInfoDto = commentService.queryCommentList(commentInfoDto);
            CommentResultParam resultParam = buildCommentResultParam(resultInfoDto);
            log.info("查询评论-controller层-queryByUserId-出参:{}", JSON.toJSONString(resultParam));
            return PageResultWrapper.page(resultParam.getList(),resultParam.getTotal().intValue(), param.getPageNum(), param.getPageSize());
        }catch (Exception e){
            log.error("查询评论-controller层-queryByUserId-异常:", e);
            return PageResultWrapper.fail("-1","查询评论异常:"+e.getMessage());
        }
    }

    private CommentResultParam buildCommentResultParam(CommentResultInfoDto resultInfoDto) {
        if(resultInfoDto==null){
            return null;
        }
        CommentResultParam resultParam = new CommentResultParam();
        resultParam.setTotal(resultInfoDto.getTotal());
        resultParam.setList(buildCommentInfoEntityList(resultInfoDto.getList()));
        return resultParam;
    }

    private List<CommentInfoEntity> buildCommentInfoEntityList(List<CommentDetailInfoDto> list) {
        if(CollectionUtils.isEmpty(list)){
            return new ArrayList<>();
        }
        List<CommentInfoEntity> resultList = new ArrayList<>();
        for (int i = 0; i < list.size(); i++) {
            CommentDetailInfoDto source = list.get(i);
            if(source==null){
                continue;
            }
            CommentInfoEntity target = buildCommentInfoEntity(source);
            resultList.add(target);

        }
        return resultList;
    }

    private CommentInfoEntity buildCommentInfoEntity(CommentDetailInfoDto source) {
        CommentInfoEntity target = new CommentInfoEntity();
        target.setUserId(source.getUserId()+"");
        target.setId(source.getId()+"");
        target.setParentId(source.getParentCommentId()==null?null:source.getParentCommentId()+"");
        target.setRootId(source.getRootCommentId()==null?null:source.getRootCommentId()+"");
        target.setModule(source.getModule());
        target.setResourceId(source.getResourceId()+"");
        target.setContent(source.getContent());
        target.setCommentTime(DateUtils.date2Str(source.getCreateTime(),DateUtils.YYYY_MM_DD_HH_MM_SS));
        target.setStarNum(source.getStarNum());
        target.setHasStar(source.getHasStar());
        target.setAvatar(source.getAvatar());
        target.setUsername(source.getUsername());
        target.setReplyNum(source.getReplyCount());
        target.setStatus(source.getStatus());
        target.setReplyList(source.getReplyList());
        return target;
    }

    private CommentInfoDto buildCommentInfoDto(QueryCommentRequestParam param) {
        if(param==null){
            return null;
        }
        CommentInfoDto commentInfoDto = new CommentInfoDto();
        commentInfoDto.setUserId(param.getUserId()!=null?Long.valueOf(param.getUserId()):null);
        commentInfoDto.setModule(param.getModule());
        commentInfoDto.setResourceId(param.getResourceId()!=null?Long.valueOf(param.getResourceId()):null);
        commentInfoDto.setScore(param.getScore());
        commentInfoDto.setOrder(param.getOrder());
        commentInfoDto.setPageNum(param.getPageNum());
        commentInfoDto.setPageSize(param.getPageSize());
        commentInfoDto.setIsDelete(CommentDeleteEnum.NORMAL.getCode());
        commentInfoDto.setReplyNum(param.getReplyNum());
        commentInfoDto.setUsername(param.getUsername());

        return commentInfoDto;
    }
}
